package com.lin.netty.module.eventLoop;

import io.netty.channel.DefaultEventLoopGroup;
import io.netty.channel.EventLoop;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.util.NettyRuntime;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.TimeUnit;

/**
 * 1、EventLoop 事件循环对象
 *
 *
 * EventLoop 本质是一个单线程执行器（同时维护了一个 Selector），里面有 run 方法处理 Channel 上源源不断的 io 事件。
 *
 * 它的继承关系比较复杂
 *  一条线是继承自 j.u.c.ScheduledExecutorService 因此包含了线程池中所有的方法
 *  另一条线是继承自 netty 自己的 OrderedEventExecutor，
 *    提供了 boolean inEventLoop(Thread thread) 方法判断一个线程是否属于此 EventLoop
 *    提供了 parent 方法来看看自己属于哪个 EventLoopGroup
 *
 *  EventLoop可以处理 IO事件、可以执行普通任务、定时任务
 *
 *
 * 2、EventLoopGroup 事件循环组
 * EventLoopGroup 是一组 EventLoop，Channel 一般会调用 EventLoopGroup 的 register 方法来绑定其中一个 EventLoop，
 * 后续这个 Channel 上的 io 事件都由此 EventLoop 来处理，一个channel只由同一个EventLoop处理（worker，保证了 io 事件处理时的线程安全）
 *
 * * 继承自 netty 自己的 EventExecutorGroup
 *   * 实现了 Iterable 接口提供遍历 EventLoop 的能力
 *   * 另有 next 方法获取集合中下一个 EventLoop
 */
@Slf4j
public class EventLoopP {
    public static void main(String[] args) {
        // 创建一个事件循环组，包含两个EventLoop，不指定的话默认是系统的 线程核心数 * 2
        EventLoopGroup eventLoopGroup = new NioEventLoopGroup(2);

        // DefaultEventLoop 只能处理普通任务、定时任务
        DefaultEventLoopGroup defaultEventLoopGroup = new DefaultEventLoopGroup();

        EventLoop eventLoop = eventLoopGroup.next();
        eventLoop.submit(() -> {
            log.info("execute common task...");
        });

        eventLoop.scheduleAtFixedRate(() -> {
            log.info("execute scheduled task...");
        },0,2, TimeUnit.SECONDS);

        log.info("main--" + NettyRuntime.availableProcessors());

    }
}
